package internal

import (
	"go.uber.org/zap"
	"gitee.com/carollia/data-sdk-go/model"
	"time"
)

// 100个event刷新一次
const BATCH_DEFAULT_MAX = 100

// 生产者,MaxSize=1就是单个事件发送
type Producer struct {
	ApiKey      string
	GameId      int
	Timezone    string
	Url         string
	Max         int
	DataList    []model.EventData
	Compression string
	Timeout     time.Duration
	Ticker      chan bool
}

func NewProducer(gameId int, secret, url, timezone string, compression string, max, timeout int) *Producer {
	if max > BATCH_DEFAULT_MAX {
		max = BATCH_DEFAULT_MAX
	}
	apiKey := secret // utils.Md5(fmt.Sprintf("EventReport_%d_%s", gameId, secret))
	return &Producer{
		Url:         url,
		Max:         max,
		DataList:    make([]model.EventData, 0, 2*max),
		ApiKey:      apiKey,
		GameId:      gameId,
		Compression: compression,
		Timeout:     time.Duration(timeout) * time.Second,
		Ticker:      make(chan bool),
		Timezone:    timezone,
	}
}

// 校验字段格式和上报数据
func (p *Producer) send(data model.EventData) (request *model.Request, err error) {
	if err = data.Normalize(); err != nil {
		return
	}
	p.DataList = append(p.DataList, data)
	// 生产任务 (事件数量或时间到指定秒数)
	request = p.getRequest(0)
	return
}

func (p *Producer) getRequest(taskType int) (request *model.Request) {
	mu.Lock()
	defer mu.Unlock()
	if len(p.DataList) <= 0 {
		return
	}
	if len(p.DataList) < p.Max {
		// 批量任务
		if taskType == 0 {
			return
		}
		if taskType == 1 {
			Logger.Debug("TimeTask 封装请求之前",zap.Int("Second", time.Now().Second()),zap.Int("len(p.DataList)", len(p.DataList)),zap.Any("dataList", p.DataList))
		}
		if taskType == 2 {
			Logger.Debug("Flush 封装请求之前",zap.Int("Second", time.Now().Second()),zap.Int("len(p.DataList)", len(p.DataList)),zap.Any("dataList", p.DataList))
		}
	}
	// 封装请求体
	request = &model.Request{
		Url: p.Url,
		RequestData: model.RequestData{
			ApiKey:      p.ApiKey,
			GameId:      p.GameId,
			Data:        p.DataList,
			Compression: p.Compression,
			Timezone:    p.Timezone,
		},
		Timeout: p.Timeout,
	}
	length := len(p.DataList)
	Logger.Debug("批量上报: 封装请求之前",
		zap.Int("len(p.DataList)", len(p.DataList)), zap.Int("len(request.RequestData.Data)", len(request.RequestData.Data)),
		zap.Any("dataList",  p.DataList), zap.Any("request.RequestData.Data", request.RequestData.Data))
	// 请求数据
	p.DataList = make([]model.EventData, 0, p.Max)
	Logger.Debug("批量上报: 封装请求之后",
		zap.Int("len(p.DataList)", len(p.DataList)), zap.Int("len(request.RequestData.Data)", len(request.RequestData.Data)),
		zap.Any("dataList",p.DataList), zap.Any("request.RequestData.Data", request.RequestData.Data))
	if len(request.RequestData.Data) != length {
		Logger.Error("封装请求后数据长度不一致")
	}
	return
}
